package cn.hyy.hrm.filter;

import cn.hyy.basic.util.AjaxResult;
import cn.hyy.hrm.RedisClient;
import com.alibaba.fastjson.JSONObject;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;

@Component
public class AccessTokenFilter extends ZuulFilter {

    @Autowired
    private RedisClient redisClient;

    private Logger logger = LoggerFactory.getLogger(AccessTokenFilter.class);

    /**
     * 过滤器的类型，它决定过滤器在请求的哪个生命周期中执行。
     * 这里定义为pre，代表会在请求被路由之前执行。
     *
     * @return
     */
    @Override
    public String filterType() {
        return "pre";
    }

    /**
     * filter执行顺序，通过数字指定。
     * 数字越大，优先级越低。
     *
     * @return
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    /**
     * 判断该过滤器是否需要被执行。这里我们直接返回了true，因此该过滤器对所有请求都会生效。
     * 实际运用中我们可以利用该函数来指定过滤器的有效范围。
     *
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 过滤器的具体逻辑
     *
     * @return
     */
    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        ctx.addZuulResponseHeader("Content-type", "text/json;charset=UTF-8");
        ctx.getResponse().setCharacterEncoding("UTF-8");

        String requestURI = request.getRequestURI();
        logger.debug("*************请求地址:"+requestURI+"***************");
        //放行
        if(requestURI.contains("api-docs")||requestURI.contains("/sso/login")||requestURI.contains("/sso/register")){
            return null;
        }

        //获取token请求头
        String token = request.getHeader("token");
        //验证请求头
        if(StringUtils.isEmpty(token)) {
            ctx.setSendZuulResponse(false);
            ctx.setResponseBody(JSONObject.toJSONString(AjaxResult.me().setSuccess(false).setMessage("请先认证!")));
            ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }
        //验证token的准确性
        Boolean exists = (Boolean) redisClient.exists("ACCESS_TOKEN:"+token).getResultObj();
        if(!exists){
            ctx.setSendZuulResponse(false);
            ctx.setResponseBody(JSONObject.toJSONString(AjaxResult.me().setSuccess(false).setMessage("token不正确!")));
            ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }
        return null;
    }
}